package org.jeecg.modules.demo.ipds.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.util.MinioUtil;
import org.jeecg.modules.demo.ipds.entity.BitList;
import org.jeecg.modules.demo.ipds.entity.ByteFrameZu;
import org.jeecg.modules.demo.ipds.entity.TreeByteList;
import org.jeecg.modules.demo.ipds.entity.TreeByteList2;
import org.jeecg.modules.demo.ipds.entity.dto.ByteBitDto;
import org.jeecg.modules.demo.ipds.entity.dto.CalculatedValueDto;
import org.jeecg.modules.demo.ipds.entity.dto.ExportFileDto;
import org.jeecg.modules.demo.ipds.mapper.TreeByteListMapper;
import org.jeecg.modules.demo.ipds.service.IBitListService;
import org.jeecg.modules.demo.ipds.service.IByteFrameZuService;
import org.jeecg.modules.demo.ipds.service.ITreeByteListService;
import org.jeecg.modules.demo.ipds.service.ITreeByteListService2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 字节列表
 * @Author: jeecg-boot
 * @Date:   2024-01-31
 * @Version: V1.0
 */
@Service
public class TreeByteListServiceImpl extends ServiceImpl<TreeByteListMapper, TreeByteList> implements ITreeByteListService {

    @Autowired
    private ITreeByteListService treeByteListService;

    @Autowired
    private IBitListService bitListService;


    @Autowired
    private ITreeByteListService2 treeByteListService2;

    @Autowired
    private IByteFrameZuService byteFrameZuService;

    @Override
    public List<TreeByteList> listByTreeId(TreeByteList treeByteList) {
        QueryWrapper<TreeByteList> queryWrapper = new    QueryWrapper<>();
        queryWrapper.eq("ip_tree_id",treeByteList.getIpTreeId());
        queryWrapper.orderByAsc("index_sx");


        List<TreeByteList> list = treeByteListService.list(queryWrapper);

        for (TreeByteList byteList : list) {
            List<List<TreeByteList2>> children = new LinkedList<>();
            QueryWrapper<ByteFrameZu> byteFrameZuQueryWrapper =new QueryWrapper<>();
            byteFrameZuQueryWrapper.eq("byte_id",byteList.getId())      ;
            byteFrameZuQueryWrapper.orderByAsc("index_sx");
            List<ByteFrameZu> byteFrameZus = byteFrameZuService.list(byteFrameZuQueryWrapper);
            for (ByteFrameZu frameZus : byteFrameZus) {
                QueryWrapper<TreeByteList2>  treeByteList2QueryWrapper=  new QueryWrapper<>();
                treeByteList2QueryWrapper.eq("pid", frameZus.getId());
                treeByteList2QueryWrapper.orderByAsc("index_sx");
                List<TreeByteList2> byteChildren = treeByteListService2.list(treeByteList2QueryWrapper);
                //设置子帧
                for (TreeByteList2 byteChild : byteChildren) {

                    QueryWrapper<BitList> bitQW = new QueryWrapper<>();
                    bitQW.eq("byte_id", byteChild.getId());
                    bitQW.orderByAsc("index_sx");
                    byteChild.setBitLists(bitListService.list(bitQW));
                }
                children.add(byteChildren);
            }
            byteList.setChildren(children);
            QueryWrapper<BitList> bitQW = new QueryWrapper<>();
            bitQW.eq("byte_id", byteList.getId());
            bitQW.orderByAsc("index_sx");
            byteList.setBitLists(bitListService.list(bitQW));
        }
        return list;
    }

    @Override
    public void insterBatch(ByteBitDto byteBitDto) {
        String ipTreeId = byteBitDto.getIpTreeId();

        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("ip_tree_id",ipTreeId);
        treeByteListService.remove(queryWrapper);
        bitListService.remove(queryWrapper);
        treeByteListService2.remove(queryWrapper);
        byteFrameZuService.remove(queryWrapper);


        List<TreeByteList> treeByteList = byteBitDto.getTreeByteList();
        if (treeByteList!=null&&treeByteList.size()>0){
            //编辑修改sn
            Integer index_sx = 1;

            for (TreeByteList byteList : treeByteList) {
                List<List<TreeByteList2>> children = byteList.getChildren();
                if (children != null && children.size() > 0) {

                    byteList.setSn(byteList.getIndex());
                    byteList.setIpTreeId(ipTreeId);
                    byteList.setIndexSx(index_sx); //设置顺序
                    treeByteListService.saveOrUpdate(byteList);
                    Integer zuIndex = 1;
                    List<Integer> lengths = new ArrayList<>();
                    for (List<TreeByteList2> child : children) {
                        //新增一个组
                        ByteFrameZu byteFrameZu = new ByteFrameZu();
                        byteFrameZu.setName("子帧"+zuIndex);
                        byteFrameZu.setIndexSx(zuIndex);
                        byteFrameZu.setByteId(byteList.getId());
                        byteFrameZu.setIpTreeId(ipTreeId);
                        byteFrameZuService.save(byteFrameZu);
                        zuIndex++;
                        Integer byteIndex2 = 1;
                        Integer sum = 0;
                        for (TreeByteList2 treeByteList2 : child) {
                            sum+=Integer.parseInt(treeByteList2.getFieldLength());
                            //新增子帧字节
                            treeByteList2.setSn(treeByteList2.getIndex());

                            treeByteList2.setPid(byteFrameZu.getId());
                            treeByteList2.setIpTreeId(ipTreeId);
                            treeByteList2.setIndexSx(byteIndex2);
                            treeByteListService2.save(treeByteList2);

                            List<BitList> bitLists = treeByteList2.getBitLists();
                            Integer index_bit_sx = 1;
                            //位保存
                            if (bitLists!=null&&bitLists.size()>0){
                                for (BitList bitList : bitLists) {
                                    bitList.setIpTreeId(ipTreeId);
                                    bitList.setIndexSx(index_bit_sx);
                                    bitList.setByteId(treeByteList2.getId());
                                    index_bit_sx ++ ;

                                    bitListService.saveOrUpdate(bitList);
                                }
                            }
                        }
                        lengths.add(sum);
                    }

                    Integer maxLength = lengths.stream().max(Comparator.comparing(Integer::intValue)).get();
                    byteList.setFieldLength(maxLength.toString());
                    treeByteListService.saveOrUpdate(byteList);

                }else {

                    byteList.setSn(byteList.getIndex());
                    byteList.setIpTreeId(ipTreeId);
                    byteList.setIndexSx(index_sx); //设置顺序
                    treeByteListService.saveOrUpdate(byteList);
                }

                index_sx ++ ;
                List<BitList> bitLists = byteList.getBitLists();
                Integer index_bit_sx = 1;

                //位保存
                if (bitLists!=null&&bitLists.size()>0){
                    for (BitList bitList : bitLists) {
                        bitList.setIpTreeId(ipTreeId);
                        bitList.setIndexSx(index_bit_sx);
                        bitList.setByteId(byteList.getId());
                        index_bit_sx ++ ;

                        bitListService.saveOrUpdate(bitList);
                    }
                }


            }


        }
    }

    @Override
    public boolean calculatedValue(CalculatedValueDto jsonObject) {

        try {
            String ipTreeId = jsonObject.getId();

            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("ip_tree_id", ipTreeId);
            //查询字节列表
            List<TreeByteList> list = treeByteListService.list(queryWrapper);
            //修改字节值
            for (TreeByteList treeByteList : list) {
                //字节类型
                String fieldType = treeByteList.getFieldType();
                if (fieldType != null && !fieldType.equals("")) {
                    //判断字节是什么类型
                    if (fieldType.equals("数据值")) {
                        //这是数据值通过type计算出的值
                        int value = calculatedFieldValue(jsonObject.getType(), treeByteList.getValueScope());
                        treeByteList.setFieldTypeValue(String.valueOf(value));

                        treeByteList.setHexNum(Integer.toHexString(calculated(String.valueOf(value))));
//                        treeByteList.s

                        treeByteListService.updateById(treeByteList);
                        continue;
                    }
                    if (treeByteList.getDefaultValue() != null && !treeByteList.getDefaultValue().equals("")) {
                        treeByteList.setFieldTypeValue(treeByteList.getDefaultValue());
                        treeByteList.setHexNum(Integer.toHexString(calculated(treeByteList.getDefaultValue())));
                        treeByteListService.updateById(treeByteList);
                    }

                }
            }

            //查询子帧字节列表
            List<TreeByteList2> treeByteList2s = treeByteListService2.list(queryWrapper);
            //修改子帧值
            for (TreeByteList2 byteList2 : treeByteList2s) {

                //字节类型
                String fieldType = byteList2.getFieldType();
                if (fieldType != null && !fieldType.equals("")) {
                    //判断字节是什么类型
                    if (fieldType.equals("数据值")) {
                        //这是数据值通过type计算出的值
                        int value = calculatedFieldValue(jsonObject.getType(), byteList2.getValueScope());
                        byteList2.setFieldTypeValue(String.valueOf(value));
                        //转十六进制数
                        byteList2.setHexNum(Integer.toHexString(calculated(String.valueOf(value))));
                        treeByteListService2.updateById(byteList2);
                        continue;

                    }
                    if (byteList2.getDefaultValue() != null && !byteList2.getDefaultValue().equals("")) {
                        byteList2.setFieldTypeValue(byteList2.getDefaultValue());
                        //转十六进制数
                        byteList2.setHexNum(Integer.toHexString(calculated(byteList2.getDefaultValue())));

                        treeByteListService2.updateById(byteList2);
                    }

                }
            }
            //重新查询出来计算校验和


            QueryWrapper treeByteQw = new QueryWrapper<>();
            treeByteQw.eq("ip_tree_id", ipTreeId);
            treeByteQw.eq("reuse_field",
                    "true");
            treeByteQw.ne("field_type", "校验和");
            //查询字节列表
            List<TreeByteList> newlist = treeByteListService.list(treeByteQw);
            List<TreeByteList2> newTreeByteList2s = treeByteListService2.list(treeByteQw);
            //拿到字节的所有值
            List<String> collect = newlist.stream().map(treeByteList -> treeByteList.getFieldTypeValue()).collect(Collectors.toList());
            List<String> collect2 = newTreeByteList2s.stream().map(treeByteList -> treeByteList.getFieldTypeValue()).collect(Collectors.toList());
            collect.addAll(collect2);

            //计算校验和值
            double sum = collect.stream().mapToDouble(Double::parseDouble).sum();
            UpdateWrapper<TreeByteList> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("ip_tree_id", ipTreeId);
            updateWrapper.eq("field_type", "校验和");
            updateWrapper.set("field_type_value", sum);
            updateWrapper.set("hex_num",Integer.toHexString(calculated(String.valueOf(sum))));
            //修改校验和
            treeByteListService.update(updateWrapper);

            Map<String, List<TreeByteList2>> collect1 = newTreeByteList2s.stream().collect(Collectors.groupingBy(TreeByteList2::getPid));
            for (String string : collect1.keySet()) {
                //子帧的校验和值
                double ziSum = collect1.get(string).stream().map(treeByteList -> treeByteList.getFieldTypeValue()).collect(Collectors.toList()).stream().mapToDouble(Double::parseDouble).sum();
                UpdateWrapper<TreeByteList2> updateWrapper2 = new UpdateWrapper<>();
                updateWrapper2.eq("ip_tree_id", ipTreeId);
                updateWrapper2.eq("field_type", "校验和");
                updateWrapper2.eq("pid", string);
                updateWrapper2.set("field_type_value", ziSum);
                updateWrapper.set("hex_num",Integer.toHexString(calculated(String.valueOf(ziSum))));
                //修改子帧校验和
                treeByteListService2.update(updateWrapper2);
            }



            //子帧校验和不知道要不要计算
            return true;
        }catch (Exception e){
            log.error("计算失败"+e.getMessage());
            return false;
        }

    }


    //如果有小数成倍数
    public int calculated(String value){
       String newValue =value;
        //判断是个几位小数
        int jiweixiaoshu = 0;
        int xiaoshu=   value.indexOf(".")+ 1;
        if (xiaoshu!=0){
            double d = Double.valueOf(value);
            jiweixiaoshu= value.length()-xiaoshu;
            int jisuan= (int) (d*Math.pow(10,jiweixiaoshu));
            newValue=String.valueOf(jisuan);
        }
        int values = Integer.parseInt(newValue);
        return values;
    }

    @Override
    public String exportFile(ExportFileDto exportFileDto) {

        String fileType = exportFileDto.getType();
        String ipTreeId = exportFileDto.getId();
        List<String> values = new ArrayList<>();
        StringBuilder string = new StringBuilder();
        String fileName = "";
        boolean first = true;
        InputStream inputStream = null;
        //十进制
        if (fileType.equals("10")){
            fileName = "十进制测试数据.txt";
            //查询字节列表
            TreeByteList treeByteList = new TreeByteList();
            treeByteList.setIpTreeId(ipTreeId);
            List<TreeByteList> list = treeByteListService.listByTreeId(treeByteList);


            for (TreeByteList byteList : list) {
                List<List<TreeByteList2>> children = byteList.getChildren();
                if (children.size()>0){
                    for (List<TreeByteList2> child : children) {
                        if (child.size()>0){
                            for (TreeByteList2 treeByteList2 : child) {
                                values.add(treeByteList2.getFieldTypeValue());
//                                System.out.println(treeByteList2.getByteName());
                            }
                        }
                    }
                }else {
                    values.add(byteList.getFieldTypeValue());
//                    System.out.println(byteList.getByteName());
                }
            }
            inputStream=new  ByteArrayInputStream(values.toString().getBytes());

        }
        //十六进制
        if (fileType.equals("16")){
            fileName = "十六进制测试数据.bin";
            //查询字节列表
            TreeByteList treeByteList = new TreeByteList();
            treeByteList.setIpTreeId(ipTreeId);
            List<TreeByteList> list = treeByteListService.listByTreeId(treeByteList);

            for (TreeByteList byteList : list) {
                List<List<TreeByteList2>> children = byteList.getChildren();
                if (children.size() > 0) {
                    for (List<TreeByteList2> child : children) {
                        if (child.size() > 0) {

                            for (TreeByteList2 treeByteList2 : child) {
                                if (first) {
                                    first = false;  // 第一个元素不添加空格
                                } else {
                                    string.append(" ");  // 其他元素前加空格
                                }
                                string.append(treeByteList2.getHexNum());
//                                values.add(treeByteList2.getHexNum());
                            }
                        }
                    }
                } else {
                    if (first) {
                        first = false;  // 第一个元素不添加空格
                    } else {
                        string.append(" ");  // 其他元素前加空格
                    }
                    string.append(byteList.getHexNum());
                    inputStream=new  ByteArrayInputStream(string.toString().getBytes(StandardCharsets.UTF_8));

                }
            }


        }


        try {
            String upload = MinioUtil.upload(inputStream, fileName);
            return upload;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean copyAdd(String id ,String type,Integer index) {

        if (type.equals("1")){
            //字节
            TreeByteList byId = treeByteListService.getById(id);
            String byteId = byId.getId();
            byId.setId(null);

            QueryWrapper<BitList> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("byte_id",byteId);
            treeByteListService.save(byId);

            List<BitList> list = bitListService.list(queryWrapper);
            for (BitList bitList : list) {
                bitList.setId(null);
                bitList.setByteId(byId.getId());
                bitListService.save(bitList);
            }

            return true;
        }
        if (type.equals("2")){
            //子帧组
            TreeByteList byId = treeByteListService.getById(id);
            String byteId = byId.getId();

            QueryWrapper<ByteFrameZu> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("byte_id",byteId);
            ByteFrameZu byteFrameZu = byteFrameZuService.list(queryWrapper).get(index);
            String zuId = byteFrameZu.getId();

                //新增一个组
                byteFrameZu.setId(null);
                byteFrameZu.setByteId(byteId);
                byteFrameZuService.save(byteFrameZu);

                QueryWrapper<TreeByteList2> treeByteList2QueryWrapper = new QueryWrapper<>();
                treeByteList2QueryWrapper.eq("pid",zuId);
            List<TreeByteList2> child = treeByteListService2.list(treeByteList2QueryWrapper);

            for (TreeByteList2 treeByteList2 : child) {
                    //新增子帧字节
                    String treeByteList2Id = treeByteList2.getId();
                    treeByteList2.setId(null);
                    treeByteList2.setPid(byteFrameZu.getId());
                    treeByteListService2.save(treeByteList2);

                    //位
                    QueryWrapper<BitList> bitListQueryWrapper = new QueryWrapper<>();
                 bitListQueryWrapper.eq("byte_id",treeByteList2Id);
                List<BitList> bitLists = bitListService.list(bitListQueryWrapper);

                    //位保存
                    if (bitLists!=null&&bitLists.size()>0){
                        for (BitList bitList : bitLists) {
                            bitList.setId(null);
                            bitList.setByteId(treeByteList2.getId());
                            bitListService.save(bitList);
                        }
                    }
                }

            //子帧组
            return true;
        }
        if (type.equals("3")){
            //子帧字节
            TreeByteList2 treeByteList2 = treeByteListService2.getById(id);
            //新增子帧字节
            String treeByteList2Id = treeByteList2.getId();

            treeByteList2.setId(null);
            treeByteListService2.save(treeByteList2);
            //位
            QueryWrapper<BitList> bitListQueryWrapper = new QueryWrapper<>();
            bitListQueryWrapper.eq("byte_id",treeByteList2Id);
            List<BitList> bitLists = bitListService.list(bitListQueryWrapper);
            //位保存
            if (bitLists!=null&&bitLists.size()>0){
                for (BitList bitList : bitLists) {
                    bitList.setId(null);
                    bitList.setByteId(treeByteList2.getId());
                    bitListService.save(bitList);
                }
            }
            return true;
        }
        if (type.equals("4")){
            //位
            BitList bitList = bitListService.getById(id);
            bitList.setId(null);
            bitListService.save(bitList);

            return true;
        }


        return false;
    }


    public int calculatedFieldValue(String type,String valueScope){

        // 拆分字符串
        List<String> list = Arrays.asList(valueScope.split(","));
        int value =0;
            if (CalculatedValueDto.calculatedValueTypeEnum.MAX.getType().equals(type)){


                value = Integer.parseInt(list.get(1));


            }

            if (CalculatedValueDto.calculatedValueTypeEnum.MIN.getType().equals(type)){
                value = Integer.parseInt(list.get(0));

            }
            if (CalculatedValueDto.calculatedValueTypeEnum.random.getType().equals(type)){
                Random random = new Random();

                int minValue = Integer.parseInt(list.get(0));
                int maxValue = Integer.parseInt(list.get(1));

                 value = random.nextInt(maxValue-minValue+1) + minValue;

            }
    return value;
    }
}
